home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 8
/
FM Towns Free Software Collection 8.iso
/
t_os
/
artemis
/
artsrc2
/
tiff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-01
|
8KB
|
303 lines
/*
tiff.c
TIFF画像セーブ・ロード関数
(200KB程度のメモリが必要)
*/
#include <stdio.h>
#include <malloc.h>
#include <egb.h>
#include <msdos.cf>
#include <ryosuke.h>
#include <tifflib.h>
#include <msdos.cf>
#include <usrlib.h>
#define DATABUF (32*1024)
#define IMAGEBUF (16*1024)
#define WORKBUF _max(DECOMP_WORK_SIZE,COMP_WORK_SIZE)
static char *databuf = NULL;
static char *imagebuf = NULL;
static char *workbuf = NULL;
static int x,y;
static FILE *fp;
static TIFFinfo tiffinfo;
/*--------------------------------------------------------*/
/* 作業用メモリの確保 */
/*--------------------------------------------------------*/
int TIFFinitwork()
// 返値 0=正常終了 -1=メモリ不足
{
if (databuf == NULL) { // 作業用メモリ領域の確保
if ((databuf = malloc(DATABUF+IMAGEBUF+WORKBUF)) == NULL)
return -1;
imagebuf = databuf + DATABUF;
workbuf = imagebuf + IMAGEBUF;
}
return 0;
}
/*--------------------------------------------------------*/
/* TIFF データの読み出し */
/*--------------------------------------------------------*/
static int load_x0, load_y0;
static int input_data(char *buf, int size)
{
fread(buf,1,size,fp);
return 0;
}
static int output_image(char *buf, int lofs, int lines)
{
struct { char *buf; short sel, sx,sy,ex,ey; } p;
p.buf = buf; p.sel = getds();
p.sx = load_x0; p.ex = load_x0 + x - 1;
p.sy = load_y0 + lofs; p.ey = load_y0 + lofs + lines - 1;
EGB_putBlock( EGB_work, 0, (char*)&p );
return 0;
/*
if (!(_wrtpage & 0x80)) {
struct { char *buf; short sel, sx,sy,ex,ey; } p;
p.buf = buf; p.sel = getds();
p.sx = load_x0; p.ex = load_x0 + x - 1;
p.sy = load_y0 + lofs; p.ey = load_y0 + lofs + lines - 1;
EGB_putBlock(EGB_work, 0, (char*)&p);
return 0;
} else {
gputblk(buf, load_x0, load_y0+lofs, x, lines, 0);
return 0;
}
*/
}
static int (*putimagefunc)() = NOFNCint;
void TIFFload_putimagefunc(int (*func)())
{
putimagefunc = func;
}
int TIFFload(char *fname, int x0, int y0)
// 返値 0=成功 -1=失敗
{
if (TIFFinitwork() != 0)
return -1;
load_x0 = x0;
load_y0 = y0;
if ((fp = fopen(fname,"rb")) == NULL)
return -1;
fread(databuf,1,DATABUF,fp); // ヘッダの読み出し
if (TIFF_getHead(databuf,DATABUF) < 0)
goto END;
int pixelsize;
int comp,fill;
long strip,clut;
if ((pixelsize = TIFF_checkMode(&x,&y,&comp,&fill,&strip,&clut)) < 0)
goto END;
if (pixelsize == 24)
goto END;
if (putimagefunc == NOFNCint)
TIFF_setLoadFunc(output_image, input_data);
else
TIFF_setLoadFunc(putimagefunc, input_data);
int img_xlen, img_ylen;
img_xlen = (pixelsize==4 ? ((x+7) & 0xfffffff8) : x);
img_ylen = IMAGEBUF / ((img_xlen*pixelsize+7)/8);
if (clut!=0) {
char plt[256*8+4];
TIFF_getPal(plt);
EGB_palette(EGB_work, 0, plt);
}
TIFF_loadImage(pixelsize,x,y,strip,fill,comp,
imagebuf,img_xlen,img_ylen,workbuf);
END:
fclose(fp);
// TIFF情報構造体の更新
{
tiffinfo.xlen = x;
tiffinfo.ylen = y;
}
return 0;
}
/*--------------------------------------------------------*/
/* TIFF データの書き込み */
/*--------------------------------------------------------*/
static int save_x1, save_y1, save_xlen, save_ylen;
static int output_data(char *buf, long size)
{
if (fwrite(buf,1,size,fp) < size)
return -1;
return 0;
}
static int input_image(char *buf,int lofs,int lines)
{
struct { char *buf; short sel, sx,sy,ex,ey; } p;
p.buf = buf; p.sel = getds();
p.sx = save_x1; p.ex = save_x1 + save_xlen - 1;
p.sy = save_y1 + lofs; p.ey = save_y1 + lofs + lines - 1;
EGB_getBlock(EGB_work, (char*)&p);
return 0;
}
#define NOFNC ((int (*)())0)
static int (*getimagefunc)() = NOFNCint;
void TIFFsave_getimagefunc(int (*func)())
{
getimagefunc = func;
}
int TIFFsave(char *fname, int x1,int y1,int xlen,int ylen, bool compress)
// 返値 0=成功 -1=画面モード/ファイル名の間違い
// -2=メモリ不足 -3=ディスク領域不足 -4=get関数エラー
{
if (TIFFinitwork() != 0)
return -2;
save_x1 = x1;
save_y1 = y1;
save_xlen = xlen;
save_ylen = ylen;
int pixelsize,headsize;
char _palet[256*8+4],*palet;
palet = NULL;
headsize = 512;
int scrmod, wrtpage;
wrtpage = EGB_getWritePage(_egbwork, getds());
if ( wrtpage == 0 )
scrmod = ( EGB_getResolution( NULL, NULL ) & 255 );
else
scrmod = ( (EGB_getResolution( NULL, NULL ) >> 8) & 255 );
if (scrmod == 3 || scrmod == 4)
{
pixelsize = 4, x = 640, y = 480;
EGB_getPalette(wrtpage, _palet);
palet = _palet;
}
else if (5 <= scrmod && scrmod <= 8)
pixelsize = 16, x = 256, y = 240;
else if (9 <= scrmod && scrmod <= 11)
pixelsize = 16, x = 320, y = 240;
else if (12 <= scrmod && scrmod <= 14)
{
pixelsize = 8, x = 640, y = 480;
EGB_getPalette(wrtpage, _palet);
palet = _palet;
headsize = 2048;
}
else if (15 <= scrmod && scrmod <=18)
pixelsize = 16, x = 512, y = 480;
else
return -1;
//
// (1) ファイルをオープンし、ヘッダのサイズ分シークする。
// ヘッダサイズ : 256色モード=2048 bytes その他モード=512 bytes
if ((fp = fopen(fname,"wb")) == NULL)
return -1;
if (fwrite(databuf,1,headsize,fp) < headsize)
{ fclose(fp); return -3; }
//
// (2) 画面データの取り出しルーチンと、ファイルへ書き出すルーチンを登録
if (getimagefunc == NOFNCint)
TIFF_setSaveFunc(output_data,input_image);
else
TIFF_setSaveFunc(output_data,getimagefunc);
//
// (3) TIFF のセーブルーチンをコールする
int img_xlen,img_ylen;
img_xlen = (pixelsize==4 ? ((save_xlen+7) & 0xfffffff8) : save_xlen);
img_ylen = IMAGEBUF / ((img_xlen*pixelsize+7)/8);
int cmp_size;
cmp_size = TIFF_saveImage(pixelsize, save_xlen, save_ylen, (compress? 5:1),
databuf, DATABUF, imagebuf, img_xlen, img_ylen,
workbuf);
if (cmp_size == -1)
{ fclose(fp); return -4; }
else if (cmp_size == -2)
{ fclose(fp); return -3; }
//
// (4) ヘッダ情報をつくる
TIFF_setHead(databuf,pixelsize,save_xlen,save_ylen,
(compress? cmp_size: 0), palet);
//
// (5) ファイルを先頭にシークして、ヘッダを書き出し、クローズ
fflush(fp);
long nowfp;
nowfp = ftell(fp);
rewind(fp);
if (fwrite(databuf,1,headsize,fp) < headsize)
{ fclose(fp); return -3; }
fflush(fp);
fseek(fp,nowfp,SEEK_SET);
fclose(fp);
// TIFF情報構造体の更新
{
tiffinfo.xlen = save_xlen;
tiffinfo.ylen = save_ylen;
}
return 0;
}
/*--------------------------------------------------------*/
/* TIFF データファイルに関する情報を得る */
/*--------------------------------------------------------*/
int TIFFgetinfo(char *fname, TIFFinfo *info)
// 返値 0=正常終了
// -1=ファイルが存在しない
// -2=TIFF形式ではない
// -3=メモリが足りない
{
if (TIFFinitwork() != 0)
return -3;
if ((fp = fopen(fname,"rb")) == NULL)
return -1;
fread(databuf,1,DATABUF,fp); // ヘッダの読み出し
fclose(fp);
if (TIFF_getHead(databuf,DATABUF) < 0)
return -2;
int xlen,ylen,pixelsize,comp,fill; long strip,clut;
if ((pixelsize = TIFF_checkMode(&xlen,&ylen,&comp,&fill,&strip,&clut)) < 0)
return -2;
info->xlen = xlen;
info->ylen = ylen;
info->compress = (comp == 1 ? NO : YES);
info->pixelsize = pixelsize;
return 0;
}
/* end of tiff.c */